<?php
/**
 * Created by jinqiang on 2024/9/29 11:32.
 * Copyright (c) 2024, Your Company. All rights reserved.
 */


namespace App\Http\Services\Soa;


use App\Http\Models\Mysql\SsyAdditionalAmountTable;
use App\Http\Models\Mysql\SsyFineAmountTable;
use App\Http\Models\Mysql\SsyJstPurchaseinOrderEmbroideryCountTable;
use App\Http\Models\Mysql\SsyJstPurchaseinOrderTable;
use App\Http\Models\Mysql\SsyProcessingFactoryNameTable;
use App\Http\Models\Mysql\SsyProcessingListTable;
use App\Http\Models\Mysql\SsyReconciliationOrderTable;
use App\Http\Models\Mysql\SsyReconciliationOrderZgTable;
use App\Http\Repository\KingdeeRepository;
use Illuminate\Support\Facades\DB;

class ReconciliationService
{
    public function search($param)
    {
        $conn = (new SsyReconciliationOrderTable())->where('type', (Int)$param['type']);
        if($param['supplier_id'] ?? ""){
            $conn = $conn->where('supplier_id', $param['supplier_id']);
        }
        if($param['recon_time'] ?? ""){
            $conn = $conn->where('recon_time', $param['recon_time']);
        }
        if($param['source_factory_groups_id'] ?? ""){
            $conn = $conn->where('source_factory_groups_id', $param['source_factory_groups_id']);
        }
        if(isset($param['status']) && $param['status'] != ""){
            $conn = $conn->where('status', (Int)$param['status']);
        }
        if(isset($param['pay_status']) && $param['pay_status'] != ""){
            $conn = $conn->where('pay_status', (Int)$param['pay_status']);
        }
        if(isset($param['is_push']) && $param['is_push'] != ""){
            $conn = $conn->where('is_push', (Int)$param['is_push']);
        }
        $res = $conn->orderBy('createtime', 'desc')->paginate((Int)$param['limit'])->toArray();
        $subject = array_column(config('scm.subject'), 'brand_name', 'supplier_id');
        foreach ($res['data'] as &$item){
            $item['brand_name'] = $subject[$item['source_factory_groups_id']] ?? $item['source_factory_groups_id'];
            $item['pay_images'] = !empty($item['pay_images']) ? unserialize($item['pay_images']) : [];
        }
        unset($item);
        return ['data' => $res['data'], 'total' => $res['total']];
    }

    public function searchXhZg($param)
    {
        $conn = new SsyReconciliationOrderZgTable();
        if($param['supplier_id'] ?? ""){
            $conn = $conn->where('supplier_id', $param['supplier_id']);
        }
        if($param['recon_time'] ?? ""){
            $conn = $conn->where('recon_time', $param['recon_time']);
        }
        if(isset($param['is_push']) && $param['is_push'] != ""){
            $conn = $conn->where($param['is_push'], (Int)$param['is_push']);
        }
        if($param['source_factory_groups_id'] ?? ""){
            $conn = $conn->where('source_factory_groups_id', $param['source_factory_groups_id']);
        }
        $res = $conn->orderBy('create_time', 'desc')->paginate((Int)$param['limit'])->toArray();
        $supplierIds = array_column($res['data'], 'supplier_id');
        $factoryMap = [];
        if(!empty($supplierIds)){
            $factoryList = (new SsyProcessingFactoryNameTable())->whereIn('supplier_id', $supplierIds)->get(['supplier_id', 'factory_name'])->toArray();
            $factoryMap = array_column($factoryList, 'factory_name', 'supplier_id');
        }
        $subject = array_column(config('scm.subject'), 'brand_name', 'supplier_id');
        foreach ($res['data'] as &$item){
            $item['brand_name'] = $subject[$item['source_factory_groups_id']] ?? $item['source_factory_groups_id'];
            $item['factory_name'] = $factoryMap[$item['supplier_id']] ?? $item['supplier_id'];
        }
        unset($item);
        return ['data' => $res['data'], 'total' => $res['total']];
    }

    public function detailXhZg($id)
    {
        $orderObj = (new SsyReconciliationOrderZgTable())->where('id', $id)->first()->toArray();
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_id', $orderObj['supplier_id'])->first();
        $orderObj['factory_name'] = $factoryObj->factory_name;
        $detail = json_decode($orderObj['detail'], true);
        $typeNos = array_unique(array_column($detail, 'type_no'));
        sort($typeNos);
        $typeNoMap = [];
        if(!empty($typeNos)){
            $typeNoList = (new SsyProcessingListTable())->whereIn('type_no', $typeNos)->groupBy(["type_no", "type_name"])->get(["type_no", "type_name"])->toArray();
            $typeNoMap = array_column($typeNoList, 'type_name', 'type_no');
        }
        $totalPrice = 0;
        foreach($detail as &$item){
            $item['totalnum'] = $item['qty'];
            $item['type_name'] = $typeNoMap[$item['type_no']] ?? "";
            $item['cost_amount'] = round((Int)$item['qty'] * (Double)$item['contract_machining_price'], 2);
            $totalPrice += $item['cost_amount'];
        }
        unset($item);
        $orderObj['list'] = $detail;
        $orderObj['total_price'] = round($totalPrice, 2);
        return $orderObj;
    }

    public function cancel($id)
    {
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        //更新回货统计表为 未抵扣
        if(!empty($reconciliationObj['purchasein_ids'])){
            $purchaseinIds = array_map(function ($item){return (Int)$item;}, unserialize($reconciliationObj['purchasein_ids']));
            $save = $reconciliationObj['type'] === 0 ? ['k_status' => 0, 'r_id' => 0] : ['e_status' => 0, 'e_id' => 0];//0 成衣 1 绣花
            (new SsyJstPurchaseinOrderEmbroideryCountTable())->updateData($purchaseinIds, $save);
            $returnList = (new SsyJstPurchaseinOrderEmbroideryCountTable())->whereIn('id', $purchaseinIds)->get(['ids'])->toArray();
            foreach ($returnList as $item){
                if(!empty($item['ids'])){
                    (new SsyJstPurchaseinOrderTable())->updateData(unserialize($item['ids']), ['k_status' => 0]);
                }
            }
        }
        //更新额外费用为 未抵扣
        if(!empty($reconciliationObj['additional_ids'])){
            $additionalIds = array_map(function ($item){return (Int)$item;}, unserialize($reconciliationObj['additional_ids']));
            (new SsyAdditionalAmountTable())->updateData($additionalIds, ['k_status' => 0]);
        }
        //更新违约赔偿为 未抵扣
        if(!empty($reconciliationObj['fine_ids'])){
            $fineIds = array_map(function ($item){return (Int)$item;}, unserialize($reconciliationObj['fine_ids']));
            (new SsyFineAmountTable())->updateData($fineIds, ['k_status' => 0]);
        }
        //更新对账单状态
        return (new SsyReconciliationOrderTable())->updateData($id, ['status' => 3]);
    }

    public function pay($id, $images)
    {
        //推送金蝶 付款后对账信息
        $pushLog = KingdeeRepository::pushReconciliationPay($id);
        if($pushLog['code'] !== 0){
            return ['code' => -1, 'msg' => $pushLog['msg'], 'data' => $pushLog];
        }
        return (new SsyReconciliationOrderTable())->updateData($id, [
            'pay_status' => 1,
            'pay_images' => serialize($images),
            'pay_time' => date('Y-m-d H:i:s')
        ]);
    }

    public function check($id, $status)
    {
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        if(!empty($reconciliationObj['purchasein_ids'])) {
            $purchaseinIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['purchasein_ids']));
            //审核不通过 更新回货统计表为 未抵扣
            if($status == 2){
                $save = $reconciliationObj['type'] === 0 ? ['k_status' => 0, 'r_id' => 0] : ['e_status' => 0, 'e_id' => 0];//0 成衣 1 绣花
                (new SsyJstPurchaseinOrderEmbroideryCountTable())->updateData($purchaseinIds, $save);
            }else{
                //审核通过 更新回货单记录 已抵扣
                $returnList = (new SsyJstPurchaseinOrderEmbroideryCountTable())->whereIn('id', $purchaseinIds)->get(['ids'])->toArray();
                foreach ($returnList as $item){
                    if(!empty($item['ids'])) {
                        (new SsyJstPurchaseinOrderTable())->updateData(unserialize($item['ids']), ['k_status' => 1]);
                    }
                }
            }
        }
        //审核不通过 更新额外费用为 未抵扣
        if(!empty($reconciliationObj['additional_ids']) && $status == 2){
            $additionalIds = array_map(function ($item){return (Int)$item;}, unserialize($reconciliationObj['additional_ids']));
            (new SsyAdditionalAmountTable())->updateData($additionalIds, ['k_status' => 0, 'r_id' => 0]);
        }
        //审核不通过 更新违约赔偿为 未抵扣
        if(!empty($reconciliationObj['fine_ids']) && $status == 2){
            $fineIds = array_map(function ($item){return (Int)$item;}, unserialize($reconciliationObj['fine_ids']));
            (new SsyFineAmountTable())->updateData($fineIds, ['k_status' => 0, 'r_id' => 0]);
        }
        //更新对账单状态
        return (new SsyReconciliationOrderTable())->updateData($id, [
            'status' => $status,
            'to_examine_time' => date("Y-m-d H:i:s"),
            'to_examine_user' => auth()->guard("api")->user()->name
        ]);
    }

    //详情
    public function detail($id)
    {
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        $reconciliationObj['list'] = [];
        $reconciliationObj['return_total_num'] = 0;
        //获取回货统计表
        if(!empty($reconciliationObj['purchasein_ids'])){
            $purchaseinIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['purchasein_ids']));
            $returnsList = (new SsyJstPurchaseinOrderEmbroideryCountTable())->whereIn('id', $purchaseinIds)->orderBy('id', 'asc')->get()->toArray();
            $processingCodes = array_column($returnsList, 'processing_code');
            $processingList = (new SsyProcessingListTable())->whereIn('processing_code', $processingCodes)->groupBY(["processing_code", "factory_contract_no"])
                ->get(["processing_code", "factory_contract_no"])->toArray();
            $factoryContractNo = array_column($processingList, 'factory_contract_no', 'processing_code');
            $totalNum = 0;
            foreach ($returnsList as &$item){
                if($reconciliationObj['type'] == 1){//绣花
                    $item['cost_amount'] = $item['total_cost_amount'];
                }
                $item['factory_contract_no'] = $factoryContractNo[$item['processing_code']] ?? "";
                $totalNum += $item['totalnum'];
            }
            unset($item);
            $reconciliationObj['list'] = $returnsList;//回货表
            $reconciliationObj['purchasein_num'] = $totalNum;//回货总数
        }
        //额外费用
        $reconciliationObj['additional_list'] = [];
        if(!empty($reconciliationObj['additional_ids'])){
            $additionalIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['additional_ids']));
            $reconciliationObj['additional_list'] = (new SsyAdditionalAmountTable())->whereIn('id', $additionalIds)->orderBy('id', 'asc')->get()->toArray();
        }
        //违约赔偿
        $reconciliationObj['fine_list'] = [];
        if(!empty($reconciliationObj['fine_ids'])){
            $fineIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['fine_ids']));
            $reconciliationObj['fine_list'] = (new SsyFineAmountTable())->whereIn('id', $fineIds)->orderBy('id', 'asc')->get()->toArray();
        }
        //对账信息汇总
        $reconciliationObj['info'] = [
            [
                'purchasein_amount' => $reconciliationObj['purchasein_amount'] ?: 0,//货款金额
                'additional_amount' => $reconciliationObj['additional_amount'] ?: 0,//额外费用
                'fine_amount' => $reconciliationObj['fine_amount'] ?: 0,//违约赔偿
                'kaip_amount' => $reconciliationObj['kaip_amount'] ?: 0,//总开票金额
                'pay_amount' => $reconciliationObj['pay_amount'] ?: 0,//总应付金额
            ]
        ];
        //工厂银行信息
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_Id', $reconciliationObj['supplier_id'])->first()->toArray();
        $reconciliationObj['bank'] = [
            [
                'bank_of_deposit' => $factoryObj['bank_of_deposit'],
                'company_head' => $factoryObj['company_head'],
                'bank_account' => $factoryObj['bank_account'],
                'opening_bank_no' => $factoryObj['opening_bank_no'],
            ]
        ];
        //获取品牌类型
        $subject = array_column(config("scm.subject"), "brand_code_s", "supplier_id");
        $reconciliationObj['brand_code'] = $subject[$reconciliationObj['source_factory_groups_id']];
        return $reconciliationObj;
    }

    //保存并下一步
    public function save($param)
    {
        list($id, $tab) = [$param['id'] ?? '', $param['tab']];
        if(empty($id) && $tab == 'return'){//创建对账单
            return $this->create($param);
        }elseif (!empty($id) && $tab == 'return'){//修改对账单
            return $this->editReturn($param);
        }elseif (!empty($id) && $tab == 'additional'){//修改对账单--额外费用
            return $this->editAdditional($param);
        }elseif (!empty($id) && $tab == 'fine'){//修改对账单--违约赔偿
            return $this->editFine($param);
        }else{
            return ['code' => -1, 'msg' => '不理解你想干啥'];
        }
    }

    //修改对账单--违约赔偿
    public function editFine($param)
    {
        $id = (Int)$param['id'];
        $selectedIds = json_decode($param['selectedIds']);
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        //违约赔偿总金额
        $fineAmount = (new SsyFineAmountTable())->whereIn('id', $selectedIds)->sum('amount');
        $data = [
            'fine_amount' => $fineAmount,
            'fine_ids' => serialize($selectedIds),
            'kaip_amount' => $reconciliationObj['purchasein_amount']+$reconciliationObj['additional_amount'],//开票金额  =回货单金额+额外费用
            'pay_amount' => $reconciliationObj['purchasein_amount']+$reconciliationObj['additional_amount']-$fineAmount//应付金额 = 回货单金额+额外费用-罚款
        ];
        $res = (new SsyReconciliationOrderTable())->updateData($id, $data);
        if($res['code'] === 0){
            return ['code' => 0, 'data' => $this->detail($id)];
        }
        return $res;
    }

    //修改对账单--额外费用
    public function editAdditional($param)
    {
        $id = (Int)$param['id'];
        $selectedIds = json_decode($param['selectedIds']);
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        //额外外费总金额
        $additionalAmount = (new SsyAdditionalAmountTable())->whereIn('id', $selectedIds)->sum('amount');
        $data = [
            'additional_amount' => $additionalAmount,
            'additional_ids' => serialize($selectedIds),
            'kaip_amount' => $reconciliationObj['purchasein_amount']+$additionalAmount,//开票金额=回货单金额+额外费用
            'pay_amount' => $reconciliationObj['purchasein_amount']+$additionalAmount-$reconciliationObj['fine_amount']//应付金额=回货单金额+额外费用-罚款
        ];
        $res = (new SsyReconciliationOrderTable())->updateData($id, $data);
        if($res['code'] === 0){
            return ['code' => 0, 'data' => $this->detail($id)];
        }
        return $res;
    }

    //修改对账单--回货单
    public function editReturn($param)
    {
        $type = (Int)$param['type'];
        $id = (Int)$param['id'];
        $selectedIds = json_decode($param['selectedIds']);
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        $returnsList = (new SsyJstPurchaseinOrderEmbroideryCountTable())->whereIn('id', $selectedIds)->get()->toArray();
        $purchaseinAmount = 0;
        foreach ($returnsList as $item){
            if($item['status'] != 2){
                return ['code' => -1, 'msg' => '回货统计单, 未审核通过: '.$item['processing_code']];
            }
            $purchaseinAmount += round($item['totalnum'] * ($type == 1 ? $item['pay_machining_price'] : $item['pay_price']), 2);
        }
        //开票金额
        $kaipAmount = $purchaseinAmount+$reconciliationObj['additional_amount']-$reconciliationObj['fine_amount'];
        $data = [
            "purchasein_amount" => $purchaseinAmount,
            "purchasein_ids" => serialize($selectedIds),
            'kaip_amount' => $kaipAmount,//开票金额=回货单金额+额外费用
            'pay_amount' => $kaipAmount//应付金额=回货单金额+额外费用-罚款
        ];
        $res = (new SsyReconciliationOrderTable())->updateData($id, $data);
        if($res['code'] === 0){
            return ['code' => 0, 'data' => $this->detail($id)];
        }
        return $res;
    }

    //新建对账单
    public function create($param)
    {
        list($selectedIds, $type, $supplierId, $date, $brandCode, $checkBStatus) = [json_decode($param['selectedIds'], true),
            (Int)$param['type'], $param['supplier_id'], $param['date'], $param['brand_code'], $param['checkBStatus']];
        $subject = array_column(config("scm.subject"), "supplier_id", "brand_code_s");
        $sourceFactoryGroupsId = $subject[$brandCode];
        //判断是否已经存在对账单
        $exist = (new SsyReconciliationOrderTable())->where('supplier_id', $supplierId)->where('type', $type)->where('recon_time', $date)->whereNotIn('status', [2, 3])
            ->where('source_factory_groups_id', $sourceFactoryGroupsId)->exists();
        if($exist){
            return ['code' => -1, 'msg' => '该工厂当前月份的对账单已经存在了'];
        }
        $returnsList = (new SsyJstPurchaseinOrderEmbroideryCountTable())->whereIn('id', $selectedIds)->get()->toArray();
        //判断合同是否签署完成
        if($checkBStatus == 'true'){
            $processingCodes = array_column($returnsList, 'processing_code');
            $contractList = DB::table("ssy_processing_list as p")
                ->join("ssy_pricing_contract as c", 'p.factory_contract_no', '=', 'c.factory_contract_no')
                ->whereIn("p.processing_code", $processingCodes)
                ->where('c.b_status', '<>', 1)
                ->groupBy(["p.factory_contract_no"])->get(["p.factory_contract_no"])->toArray();
            if(!empty($contractList)){
                $contractList = array_map(function ($item){return (Array)$item;}, $contractList);
                return ['code' => -1, 'msg' => '合同号: '.implode(", ", array_column($contractList, 'factory_contract_no')).' 还未签署完成'];
            }
        }
        $purchaseinAmount = 0;
        foreach ($returnsList as $item){
            if($item['status'] != 2){
                return ['code' => -1, 'msg' => '回货统计单, 未审核通过: '.$item['processing_code']];
            }
            $purchaseinAmount += round($item['totalnum'] * ($type == 1 ? $item['pay_machining_price'] : $item['pay_price']), 2);
        }
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_id', $supplierId)->first(['factory_name']);
        $renumber = "DZ".$supplierId.str_replace("-", "", $date).time();
        $data = [
            "supplier_id" => $supplierId,
            "renumber" => $renumber,
            "createtime" => date('Y-m-d H:i:s'),
            "recon_time" => $date,
            "purchasein_amount" => $purchaseinAmount,
            "kaip_amount" => $purchaseinAmount,//开票金额
            "pay_amount" => $purchaseinAmount,//支付金额
            "purchasein_ids" => serialize($selectedIds),
            "factory_name" => $factoryObj->factory_name ?? "",
            "source_factory_groups_id" => $sourceFactoryGroupsId,
            'adduser' => auth()->guard("api")->user()->name,
            "type" => $type//0 成衣 1 绣花
        ];
        $res = (new SsyReconciliationOrderTable())->createData($data);
        if($res['code'] === 0){
            return ['code' => 0, 'data' => $this->detail($res['id'])];
        }
        return $res;
    }

    //确认对账单
    public function finish($id)
    {
        $reconciliationObj = (new SsyReconciliationOrderTable())->where('id', $id)->first()->toArray();
        $type = $reconciliationObj['type'];
        //更新回货统计表为 已抵扣
        if(!empty($reconciliationObj['purchasein_ids'])){
            $purchaseinIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['purchasein_ids']));
            (new SsyJstPurchaseinOrderEmbroideryCountTable())->updateData($purchaseinIds, [
                ($type ? "e_id" : "r_id") => $reconciliationObj['id'],
                ($type ? "e_status" : "k_status") => 2
            ]);
        }
        //更新额外费用为 已抵扣
        if(!empty($reconciliationObj['additional_ids'])) {
            $additionalIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['additional_ids']));
            (new SsyAdditionalAmountTable())->updateData($additionalIds, ["r_id" => $reconciliationObj['id'], "k_status" => 2]);
        }
        //更新违约赔偿为 已抵扣
        if(!empty($reconciliationObj['fine_ids'])) {
            $fineIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['fine_ids']));
            (new SsyFineAmountTable())->updateData($fineIds, ["r_id" => $reconciliationObj['id'], "k_status" => 2]);
        }
        //回写回货统计表的开票金额, 核价审核的时候会修改实付价
        $this->setBillingAmount($reconciliationObj);

        return (new SsyReconciliationOrderTable())->updateData($reconciliationObj['id'], ['data_status' => 1]);
    }

    public function setBillingAmount($reconciliationObj)
    {
        //回货统计单
        $purchaseinIds = [];
        if(!empty($reconciliationObj['purchasein_ids'])) {
            $purchaseinIds = array_map(function ($item) {return (int)$item;}, unserialize($reconciliationObj['purchasein_ids']));
        }
        if(empty($purchaseinIds)){
            return false;
        }
        $returnsList = (new SsyJstPurchaseinOrderEmbroideryCountTable())->whereIn('id', $purchaseinIds)->get()->toArray();
        foreach ($returnsList as $item){
            (new SsyJstPurchaseinOrderEmbroideryCountTable())->updateData($item['id'], [
                'billing_amount' => $item['cost_amount'],
                'emb_billing_amount' => $item['total_cost_amount']
            ]);
        }
    }
}
